package com.czk.server;

import com.sun.xml.internal.messaging.saaj.util.ByteInputStream;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.handler.stream.ChunkedStream;
import io.netty.util.ReferenceCountUtil;

/**
 * @Author:ChenZhangKun
 * @Date: 2021/5/6 10:59
 */
public class MyServerChunkHandler extends ChannelOutboundHandlerAdapter {
    @Override
    public void write(ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
        // 内容·1验证
        if (!(msg instanceof ByteBuf)) {
            super.write(ctx, msg, promise);
            return;
        }
        // 强转
        ByteBuf buf = (ByteBuf) msg;
        byte[] data = this.getData(buf);
        // 写入流
        ByteInputStream byteInputStream = new ByteInputStream();
        byteInputStream.setBuf(data);
        // 将消息份块成10个字节
        ChunkedStream chunkedStream = new ChunkedStream(byteInputStream, 10);
        // 管道传输承诺
        ChannelProgressivePromise progressivePromise = ctx.channel().newProgressivePromise();
        progressivePromise.addListener(new ChannelProgressiveFutureListener() {
            @Override
            public void operationProgressed(ChannelProgressiveFuture channelProgressiveFuture, long l, long l1) throws Exception {

            }

            @Override
            public void operationComplete(ChannelProgressiveFuture channelProgressiveFuture) throws Exception {
                if (channelProgressiveFuture.isSuccess()) {
                    System.out.println("消息发送成功 success");
                    promise.setSuccess();
                } else {
                    System.out.println("消息发送失败 failure：" + channelProgressiveFuture.cause());
                    promise.setFailure(channelProgressiveFuture.cause());
                }
            }
        });
        ReferenceCountUtil.release(msg);
        ctx.write(chunkedStream, progressivePromise);
    }

    private byte[] getData(ByteBuf buf) {

        if (buf.hasArray()) {
            // 返回字节对象
            return buf.array().clone();
        }
        byte[] data = new byte[buf.readableBytes() - 1];
        buf.readBytes(data);
        return data;
    }
}
